﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using HitachiLib.Utils;
using HitachiLib.Data;
using HitachiLib.HitachiServiceRef;
using HitachiApp.Model.Utils;

namespace HitachiApp.Model.Projects
{
    public class ProjectManageViewModel : INotifyPropertyChanged
    {
        private SortableObservableCollection<ProjectManageItem> root_items = new SortableObservableCollection<ProjectManageItem>();
        private ProjectManageItem current_selected;
        private ProjectManageItem current_selected_help;
        private bool loaded = false;
        private Resource current_login;

        public bool Loaded
        {
            get { return loaded; }
        }
        public SortableObservableCollection<ProjectManageItem> RootProjects
        {
            get { return root_items; }
            set { root_items = value; }
        }

        private ProjectManageItem current_selected_parent;
        public ProjectManageItem CurrentSelected
        {
            get { return current_selected; }
            set {
                current_selected = value;
                if (current_selected.Parent != current_selected_parent && !current_selected.Selected)
                {
                    foreach (ProjectManageItem pmi in root_items)
                    {
                        pmi.ClearSelected();
                    }
                    current_selected_parent = current_selected.Parent;
                }
                current_selected.Selected = !current_selected.Selected;
                RaisePropertyChanged("CurrentSelected");
            }
        }

        public ProjectManageItem CurrentSelectedHelp
        {
            get { return current_selected_help; }
            set {
                current_selected_help = value;
                RaisePropertyChanged("CurrentSelectedHelp");
            }
        }

        public void Load(Resource resource)
        {
            if (resource != null)
                current_login = resource;
            else
                resource = current_login;
            HitachiServiceClient client = WCFClient.GetClient();
            client.GetWholeManageDataByResourceIdCompleted +=
                new EventHandler<GetWholeManageDataByResourceIdCompletedEventArgs>(client_GetWholeManageDataByResourceIdCompleted);
            WCFClient.Retain();
            client.GetWholeManageDataByResourceIdAsync(resource.Data.ID);
        }

        public void LoadWholeManageData(WholeManageData data)
        {
            List<ProjectManageItem> all = new List<ProjectManageItem>();
            foreach (ProjectData pd in data.Projects)
            {
                ProjectManageItem pi = new ProjectManageItem();
                pi.Data = Project.GetUnique(pd);
                all.Add(pi);
            }
            root_items.Clear();
            LinkProjects(all);
            loaded = true;
            RaisePropertyChanged("RootProjects");
            RaisePropertyChanged("Loaded");
        }

        private void client_GetWholeManageDataByResourceIdCompleted(object sender, GetWholeManageDataByResourceIdCompletedEventArgs e)
        {
            WCFClient.Release();
            WholeManageData data = e.Result;
            LoadWholeManageData(data);
        }

        public void UpdateCurrentSelected()
        {
            if (current_selected != null)
            {
                HitachiServiceClient client = WCFClient.GetClient();
                client.UpdateProjectCompleted +=
                    new EventHandler<UpdateProjectCompletedEventArgs>(client_UpdateProjectCompleted);
                WCFClient.Retain();
                client.UpdateProjectAsync(current_selected.Data.Data);
            }
            RaisePropertyChanged("RootProjects");
        }

        private void client_UpdateProjectCompleted(object sender, UpdateProjectCompletedEventArgs e)
        {
            WCFClient.Release();
            if (!e.Result)
            {
                System.Windows.Browser.HtmlPage.Window.Alert("更新失败");
            }
        }

        private void client_UpdateProjectsCompleted(object sender, UpdateProjectsCompletedEventArgs e)
        {
            WCFClient.Release();
            try
            {
                object o = e.Result;
            }
            catch (Exception ee)
            {
                System.Windows.Browser.HtmlPage.Window.Alert(ee.Message);
            }
        }

        public void MoveSelectedItemTo(ProjectManageItem new_parent)
        {
            if (current_selected_parent != null)
            {
                if (current_selected_parent == new_parent)
                    return;
                List<ProjectManageItem> to_move = new List<ProjectManageItem>();
                foreach (ProjectManageItem pmi in current_selected_parent.Children)
                {
                    if (pmi.Selected)
                        to_move.Add(pmi);
                }
                if (to_move.Contains(new_parent))
                    return;
                foreach (ProjectManageItem pmi in to_move)
                {
                    MoveProjectItem(pmi, new_parent);
                    pmi.Selected = false;
                }
                MoveProjects(to_move, new_parent);
                Sort(new_parent.Children);
            }
        }

        private void MoveProjects(List<ProjectManageItem> to_move, ProjectManageItem new_parent)
        {
            ObservableCollection<ProjectData> pd_list = new ObservableCollection<ProjectData>();
            foreach (ProjectManageItem pmi in to_move)
            {
                pd_list.Add(pmi.Data.Data);
            }
            HitachiServiceClient client = WCFClient.GetClient();
            client.UpdateProjectsCompleted +=
                new EventHandler<UpdateProjectsCompletedEventArgs>(client_UpdateProjectsCompleted);
            WCFClient.Retain();
            client.UpdateProjectsAsync(pd_list);
        }

        public void MoveProjectItem(ProjectManageItem project, ProjectManageItem new_parent)
        {
            ProjectManageItem old_parent = project.Parent;
            if (old_parent != null)
            {
                old_parent.Children.Remove(project);
                new_parent.Children.Add(project);
                project.Parent = new_parent;
                MoveProjectInUI(project.Data, new_parent.Data);
            }
        }

        private void MoveProjectInUI(Project project, Project new_parent)
        {
            Project old_parent = project.Parent;
            old_parent.Children.Remove(project.Id);
            new_parent.AddChild(project);
            project.Data.ParentID = new_parent.Id;
            project.Parent = new_parent;
        }

        private void LinkProjects(List<ProjectManageItem> project_items)
        {
            Dictionary<int, ProjectManageItem> m = new Dictionary<int, ProjectManageItem>();
            Dictionary<int, ProjectManageItem> added = new Dictionary<int, ProjectManageItem>();
            root_items.Clear();
            foreach (ProjectManageItem pmi in project_items)
            {
                if (!m.ContainsKey(pmi.Data.Id))
                    m.Add(pmi.Data.Id, pmi);
            }
            foreach (ProjectManageItem pmi in project_items)
            {
                AddProjectWithParent(m, added, pmi);
            }
            SortAll(root_items);
        }

        private void AddProjectWithParent(Dictionary<int, ProjectManageItem> all, Dictionary<int, ProjectManageItem> added, ProjectManageItem pmi)
        {
            if (added.ContainsKey(pmi.Data.Id))
                return;
            if (!all.ContainsKey(pmi.Data.Data.ParentID))
            {
                root_items.Add(pmi);
            }
            else
            {
                ProjectManageItem parent = all[pmi.Data.Data.ParentID];
                pmi.Parent = parent;
                if (!parent.Children.Contains(pmi))
                    parent.Children.Add(pmi);
                AddProjectWithParent(all, added, parent);
            }
            added.Add(pmi.Data.Id, pmi);
        }

        private void SortAll(SortableObservableCollection<ProjectManageItem> item)
        {
            Sort(item);
            foreach(ProjectManageItem sub_item in item)
            {
                SortAll(sub_item.Children);
            }
        }

        public void Sort(SortableObservableCollection<ProjectManageItem> item)
        {
            item.Sort(ProjectManageItem.CompareByDevID);
        }

        #region PropertChanged Block
        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion
    }
}
